home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 21
/
Cream of the Crop 21 (Terry Blount) (October 1996).iso
/
sound
/
rsynth22.zip
/
HPLAY.C
< prev
next >
Wrap
Text File
|
1996-09-13
|
8KB
|
326 lines
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#define INCL_DOSPROCESS
#define INCL_DOSSEMAPHORES
#include <os2.h>
#define INCL_OS2MM
#include <os2me.h>
#include "proto.h"
#include "getargs.h"
#include "hplay.h"
/* PlayList Entry */
typedef struct _PLE {
ULONG operation;
ULONG operand1;
ULONG operand2;
ULONG operand3;
}PLE;
long samp_rate = 8000;
long bits = 8;
int quiet = FALSE;
static unsigned long sem = 0;
static unsigned long tid = 0;
struct PlayDataList
{
unsigned char *charbuff;
unsigned short *shortbuff;
int n;
struct PlayDataList *next;
};
static struct PlayDataList *List=0;
void mci_err(ULONG rc)
{
const rsize = 128;
char rbuff[rsize];
ULONG rc2 = mciGetErrorString(rc, // error code
rbuff, // return buffer
rsize); // rbuff size
if (rc2 == MCIERR_SUCCESS)
fprintf(stderr,"MCI error: %s\n\n",rbuff);
else
fprintf(stderr,"error # %d has occured!\n\n", rc);
}
void playbuf( void *playbuf, int n)
{
MCI_PLAY_PARMS mpp;
MCI_GENERIC_PARMS mgp;
MCI_WAVE_SET_PARMS wsp;
ULONG rc;
MCI_OPEN_PARMS mop;
PLE playlist[2];
if(playbuf)
{
playlist[0].operation = DATA_OPERATION;
playlist[0].operand1 = (long) playbuf;
playlist[0].operand2 = n;
if(bits == 16) playlist[0].operand2 = n*2;
playlist[0].operand3 = 0;
playlist[1].operation = EXIT_OPERATION;
mop.hwndCallback = 0;
mop.usDeviceID = 0;
mop.pszDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO_NAME;
mop.pszElementName = (void *)&playlist[0];
rc = mciSendCommand(0,
MCI_OPEN, // open message
MCI_WAIT | MCI_OPEN_SHAREABLE | // message flags
MCI_OPEN_PLAYLIST,
&mop, // parameters
0);
if (rc != MCIERR_SUCCESS) mci_err(rc);
// set device parameters
wsp.hwndCallback = 0;
wsp.ulSamplesPerSec = samp_rate;
wsp.usBitsPerSample = bits;
wsp.usChannels = 1;
rc = mciSendCommand(mop.usDeviceID,
MCI_SET,
MCI_WAIT |
MCI_WAVE_SET_SAMPLESPERSEC,
&wsp,
0);
if (rc != MCIERR_SUCCESS) mci_err(rc);
mpp.hwndCallback = 0;
rc = mciSendCommand(mop.usDeviceID,
MCI_SET,
MCI_WAIT |
MCI_WAVE_SET_BITSPERSAMPLE,
&wsp,
0);
if (rc != MCIERR_SUCCESS) mci_err(rc);
mpp.hwndCallback = 0;
rc = mciSendCommand(mop.usDeviceID,
MCI_SET,
MCI_WAIT |
MCI_WAVE_SET_CHANNELS,
&wsp,
0);
if (rc != MCIERR_SUCCESS) mci_err(rc);
mpp.hwndCallback = 0;
rc = mciSendCommand(mop.usDeviceID,
MCI_PLAY,
MCI_WAIT,
&mpp,
0);
if (rc != MCIERR_SUCCESS) mci_err(rc);
// close device
mgp.hwndCallback = 0;
rc = mciSendCommand(mop.usDeviceID,
MCI_CLOSE,
MCI_WAIT,
&mgp,
0);
if (rc != MCIERR_SUCCESS) mci_err(rc);
free(playbuf);
_control87(EM_INVALID | EM_DENORMAL | EM_ZERODIVIDE | EM_OVERFLOW | EM_UNDERFLOW | EM_INEXACT, MCW_EM);
}
}
void PlayThread( void *arg)
{
struct PlayDataList *l=NULL;
unsigned long timesposted;
unsigned long rc;
for(;;)
{
rc = DosWaitEventSem(sem, -1);
if(rc)
return;
rc = DosResetEventSem(sem, ×posted);
if(!rc || rc == 300)
{
while(timesposted)
{
if(!l)
l=List;
else
l=l->next;
if(!l)
return;
if(bits == 8)
playbuf(l->charbuff,l->n);
else if (bits == 16)
playbuf(l->shortbuff, l->n);
timesposted--;
}
}
else
return;
}
return;
}
int
audio_init(int argc, char **argv)
{
int rate;
rate = 8;
argc = getargs("Audio Initialization", argc, argv,
"r", "%d", &rate, "Sample Rate in kHz - 8, 11, 22, or 44",
"Q", NULL, &quiet, "+Q for no sound output (-Q Default)",
"b", "%d", &bits, "Chunk size of playback sample 8 (def) or 16",
NULL);
if (help_only)
return (argc);
switch(rate)
{
case 8 : samp_rate = 8000;
break;
case 11 : samp_rate = 11025;
break;
case 22 : samp_rate = 22050;
break;
case 44 : samp_rate = 44100;
break;
default : samp_rate = 8000;
}
if (bits != 16)
bits = 8;
DosCreateEventSem(NULL,&sem,0,0);
tid = _beginthread(PlayThread,0,8096,0);
DosSetPriority(PRTYS_THREAD,PRTYC_TIMECRITICAL,1,tid);
return (argc);
}
void
audio_term(void)
{
DosPostEventSem(sem);
DosWaitThread(&tid,DCWW_WAIT);
DosCloseEventSem(sem);
}
void
audio_play(int n, short *data)
{
ULONG rc;
if (!quiet)
{
if (bits == 8)
{
unsigned char *plabuf;
plabuf = (unsigned char *) malloc(n);
if (plabuf)
{
unsigned char *p = plabuf;
unsigned char *e = p + n;
short temp;
while (p < e)
{
temp = *data / 128;
*p = temp + 128;
p++;
data++;
}
if(!List)
{
List = (struct PlayDataList *)malloc(sizeof(struct PlayDataList));
List->next = NULL;
List->charbuff=plabuf;
List->n = n;
DosPostEventSem(sem);
}
else
{
struct PlayDataList *li = List;
while(li->next)
li=li->next;
li->next=(struct PlayDataList *)malloc(sizeof(struct PlayDataList));
li=li->next;
li->next = NULL;
li->charbuff=plabuf;
li->n = n;
DosPostEventSem(sem);
}
}
else
{
fprintf(stderr, "Insufficient memory for Play Buffer\n\n");
return;
}
}
else /* if bits == 16 */
{
short *plabuf;
plabuf = (short *) malloc(n * sizeof(short));
if (plabuf)
{
short *p = plabuf;
short *e = p + n;
while (p < e)
{
*p = *data;
p++;
data++;
}
if(!List)
{
List = (struct PlayDataList *)malloc(sizeof(struct PlayDataList));
List->next = NULL;
List->shortbuff=plabuf;
List->n = n;
DosPostEventSem(sem);
}
else
{
struct PlayDataList *li = List;
while(li->next)
li=li->next;
li->next=(struct PlayDataList *)malloc(sizeof(struct PlayDataList));
li=li->next;
li->next = NULL;
li->shortbuff=plabuf;
li->n = n;
DosPostEventSem(sem);
}
}
else
{
fprintf(stderr, "Insufficient memory for Play Buffer\n\n");
return;
}
}
}
}